/*****************************************************************************/
/**
*
* @file bsp_usart.c
*
* User defined functions about USART of stm32.
* Target device: STM32F103RET6.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver   Who    Date   	Changes
* ----- ---- ---------- -------------------------------------------------------
* 0.01  abu  02/10/2020 Created
* </pre>
*
*------------------------------------------------------------------------------
* Author:	abu
*					E-mail:	abu_liu@opencores.org
*------------------------------------------------------------------------------
*
******************************************************************************/

/***************************** Include Files *********************************/
#include "bsp_usart.h"

extern ESP8266_RECV ESP8266_Recv_Info;

/************************** Function Prototypes ******************************/

/*****************************************************************************/
/**
*
* @brief	Initialise usart1.
*
* @param	baudrate: baud rate.
* @param  None.	
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void USART1_Init(uint32_t baudrate)
{
	GPIO_InitTypeDef USART1_GPIO_Init_Struct;
	USART_InitTypeDef USART1_Init_Struct;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	//open gpio port clock and usart clock
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
	//====================gpio related========================
	//tx gpio pin, PA9
	USART1_GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_9;
	USART1_GPIO_Init_Struct.GPIO_Speed = GPIO_Speed_50MHz;
	USART1_GPIO_Init_Struct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &USART1_GPIO_Init_Struct);
	
	//rx gpio pin, PA10
	USART1_GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_10;
	USART1_GPIO_Init_Struct.GPIO_Speed = GPIO_Speed_50MHz;
	USART1_GPIO_Init_Struct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &USART1_GPIO_Init_Struct);
	
	//====================usart related========================
	//initialise usart
	USART1_Init_Struct.USART_BaudRate = baudrate;
	USART1_Init_Struct.USART_WordLength = USART_WordLength_8b;
	USART1_Init_Struct.USART_StopBits = USART_StopBits_1;
	USART1_Init_Struct.USART_Parity = USART_Parity_No;
	USART1_Init_Struct.USART_Mode = (USART_Mode_Rx|USART_Mode_Tx);
	USART1_Init_Struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	
	USART_Init(USART1, &USART1_Init_Struct);

	//enable receive interrupt
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	
	//enable usart1
	USART_Cmd(USART1,ENABLE);

	//NVIC configuration
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

/*****************************************************************************/
/**
*
* @brief	USART1 interrupt handler.
*
* @param	None.
* @param  None.	
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void USART1_IRQHandler(void)
{
	uint8_t uctemp;
	if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
	{
		uctemp = USART_ReceiveData(USART1);
		if(uctemp == '\r')
			USART_SendString(USART1,"\n\r");
		else
			USART_SendData(USART1,uctemp);
	}
}

/*****************************************************************************/
/**
*
* @brief	Initialise usart2.
*
* @param	baudrate: baud rate.
* @param  None.	
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void USART2_Init(uint32_t baudrate)
{
	GPIO_InitTypeDef USART2_GPIO_Init_Struct;
	USART_InitTypeDef USART2_Init_Struct;
	NVIC_InitTypeDef NVIC_InitStructure;
	
	//open gpio port clock and usart clock
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
	
	//====================gpio related========================
	//tx gpio pin, PA2
	USART2_GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_2;
	USART2_GPIO_Init_Struct.GPIO_Speed = GPIO_Speed_50MHz;
	USART2_GPIO_Init_Struct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &USART2_GPIO_Init_Struct);
	
	//rx gpio pin, PA3
	USART2_GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_3;
	USART2_GPIO_Init_Struct.GPIO_Speed = GPIO_Speed_50MHz;
	USART2_GPIO_Init_Struct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &USART2_GPIO_Init_Struct);
	
	//====================usart related========================
	//initialise usart
	USART2_Init_Struct.USART_BaudRate = baudrate;
	USART2_Init_Struct.USART_WordLength = USART_WordLength_8b;
	USART2_Init_Struct.USART_StopBits = USART_StopBits_1;
	USART2_Init_Struct.USART_Parity = USART_Parity_No;
	USART2_Init_Struct.USART_Mode = (USART_Mode_Rx|USART_Mode_Tx);
	USART2_Init_Struct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;	
	USART_Init(USART2, &USART2_Init_Struct);

	//enable receive interrupt
	USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);
	
	//enable usart1
	USART_Cmd(USART2,ENABLE);

	//NVIC configuration
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

/*****************************************************************************/
/**
*
* @brief	USART2 interrupt handler.
*
* @param	None.
* @param  None.	
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void USART2_IRQHandler(void)
{
	if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)
	{
		//if received bytes are too many, ignore them
		if(ESP8266_Recv_Info.dataLen > ESP8266_RECV_BUFFER_SIZE)
			ESP8266_Recv_Info.dataLen = 0;

		//dataLen will always be <= ESP8266_RECV_BUFFER_SIZE here, so just store
		//the byte first, then plus dataLen by 1.
		ESP8266_Recv_Info.buf[ESP8266_Recv_Info.dataLen] = USART_ReceiveData(USART2);
		ESP8266_Recv_Info.dataLen++;	//count bytes that are already received
		
		USART_ClearFlag(USART2, USART_FLAG_RXNE);
	}
}

/*****************************************************************************/
/**
*
* @brief	USARTx send one byte.
*
* @param	USARTx: USART port, USART1\USART2\USART3.
* @param  data: data to be sent through USART port.	
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void USART_SendByte(USART_TypeDef *USARTx, unsigned char data)
{
	USART_SendData(USARTx, data);
	
	//wait for send register to be empty
	while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);
}

/*****************************************************************************/
/**
*
* @brief	USART send one string.
*
* @param	USARTx:USART port, USART1\USART2\USART3.
* @param  str: pointer of the string to be sent.	
*
* @return	None.
*
* @note		None.
*
******************************************************************************/
void USART_SendString(USART_TypeDef *USARTx, unsigned char *str)
{
	unsigned int n = 0;
	
	USART_ClearFlag(USARTx,USART_FLAG_TC);

	while(*(str+n) != '\0')
	{
		USART_SendByte(USARTx, *(str+n));
		n = n + 1;//n++;
	}
	
	//wait for send register to be empty
	while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);

	
}
